package com.example.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.cache.Cacheable;
import com.foxinmy.weixin4j.cache.RedisCacheStorager;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.XmlResult;
import com.foxinmy.weixin4j.jssdk.JSSDKAPI;
import com.foxinmy.weixin4j.jssdk.JSSDKConfigurator;
import com.foxinmy.weixin4j.mp.WeixinProxy;
import com.foxinmy.weixin4j.mp.api.OauthApi;
import com.foxinmy.weixin4j.mp.datacube.ArticleDatacubeShare;
import com.foxinmy.weixin4j.mp.model.OauthToken;
import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.pay.WeixinPayProxy;
import com.foxinmy.weixin4j.pay.payment.mch.MchPayRequest;
import com.foxinmy.weixin4j.pay.payment.mch.Order;
import com.foxinmy.weixin4j.token.TicketManager;
import com.foxinmy.weixin4j.type.TicketType;
import com.foxinmy.weixin4j.util.Consts;
import com.foxinmy.weixin4j.util.IOUtil;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
import com.foxinmy.weixin4j.xml.XmlStream;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
@RestController
@RequestMapping("pay")
public class PayController {

    @Resource
    private WeixinPayProxy weixinPayProxy;
    @Resource
    private WeixinProxy weixinProxy;
    @Resource
    private RedisCacheStorager<OauthToken> redisCacheStorager;

    /**
     * 1.微信公众平台配置授权域名
     * 微信获取code的地址组装，code主要用于获取access_token并获取用户openid
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("dispatcher")
    public void redirect (HttpServletRequest request, HttpServletResponse response) throws IOException {
        OauthApi oauthApi = weixinProxy.getOauthApi();
        String userAuthorizationURL = oauthApi.getUserAuthorizationURL("http://192.168.1.182:8082/pay/userinfo", "1111", "snsapi_base");
        System.out.println(userAuthorizationURL);
        response.sendRedirect(userAuthorizationURL);
    }

    /**
     * 请求转发获取code值并获取access_token 进而获取用户openid
     * @param code
     * @throws WeixinException
     */
    @GetMapping("userinfo")
    public void userinfo(@RequestParam("code") String code, HttpServletRequest request) throws WeixinException {
        OauthApi oauthApi = weixinProxy.getOauthApi();


        OauthToken authorizationToken = redisCacheStorager.lookup("wx_access_token");
        if (authorizationToken == null){
            authorizationToken = oauthApi.getAuthorizationToken(code);
            redisCacheStorager.caching("wx_access_token", authorizationToken);
        }
        User authorizationUser = oauthApi.getAuthorizationUser(authorizationToken);
        System.out.println(authorizationUser);
        HttpSession session = request.getSession();
        session.setAttribute("OPENID", authorizationUser.getOpenId());
    }

    /**
     * 1.微信支付配置jsapi授权域名
     * 发起支付请求
     * @return
     */
    @GetMapping("payment")
    public ResponseEntity<?> payment (){
        String openId = "用户的唯一标识,如owGBft_vbBbOaQOmpEUE4xDLeRSU";
        String body = "支付描述,如订单费用";
        String outTradeNo = "商户侧唯一订单号,如18789913341";
        double totalFee = 1d; // 订单金额 单位元
        String notifyUrl = "支付完成后的回调地址,如http://wx.xxx.com/pay/notify";
        String createIp = "发起支付时的客户端IP地址,如192.168.1.1";
        String attach = "支付时的附加信息,在回调时会原样带上,可为空";
        try {
            MchPayRequest jsPayRequest = weixinPayProxy.createJSPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
            return ResponseEntity.ok("发起地址："+jsPayRequest.toRequestString());
        } catch (WeixinException e) {
            log.error("发起支付异常：{}", e.getErrorDesc());
            return ResponseEntity.ok("error");
        }


    }

    /**
     * 回调
     * @param input
     * @return
     * @throws IOException
     */
    @PostMapping("notify")
    public String payNotify(InputStream input) throws IOException {
        //获取订单信息
        String content = StringUtil.newStringUtf8(IOUtil.toByteArray(input));
        Order order = ListsuffixResultDeserializer.deserialize(content,
                Order.class);
        log.info("jsapi_notify_order_info:", order);
        //查到订单是否存在，订单状态是否正确，确保不重复处理
        //验证签名
        String sign = order.getSign();
        String valid_sign = weixinPayProxy.getWeixinSignature().sign(order);
        log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign);
        if (!sign.equals(valid_sign)) {
            return XmlStream.toXML(new XmlResult(Consts.FAIL, "签名错误"));
        }

        return XmlStream.toXML(new XmlResult(Consts.SUCCESS, ""));
    }

    @CrossOrigin
    @GetMapping("share")
    public ResponseEntity<?> share() throws WeixinException {
        JSSDKConfigurator jssdkConfigurator = new JSSDKConfigurator(weixinProxy.getTicketManager(TicketType.jsapi));
        jssdkConfigurator.apis(JSSDKAPI.updateAppMessageShareData, JSSDKAPI.updateTimelineShareData); // 分享功能
        jssdkConfigurator.debugMode();
        String config = jssdkConfigurator.toJSONConfig("http://192.168.1.182:8081/wx/share");
        return ResponseEntity.ok(config);
    }
}
